﻿namespace DimensionsHelper.Common.Contracts.Metadata;

/// <summary>
///     存储元数据中的字符串内容，保持读取时的 CDATA 设置。
/// </summary>
public interface IMetadataText
{
    /// <summary>
    ///     文本所在的文档对象。
    /// </summary>
    IMetadataDocument Document { get; }

    /// <summary>
    ///     指示读取或写入时是否将文本内容包含到 CDATA　中。
    /// </summary>
    bool CData { get; }

    /// <summary>
    ///     当前文本的字符串内容。
    /// </summary>
    string Text { get; }

    /// <summary>
    ///     当前字符串所在的上下文类型。
    /// </summary>
    string Context { get; }

    /// <summary>
    ///     当前字符串所在的语言类型。
    /// </summary>
    ILanguage? Language { get; }

    /// <summary>
    ///     获取或设置文本的语言名称。
    /// </summary>
    string LanguageName { get; set; }
}

/// <summary>
///     用于存储MDM文档中文本描述，文本描述需要分别区分上下文类型和语言，在存储和读取时需要对应。
/// </summary>
public interface IMetadataLabel : IMetadataObject, IMetadataStringKeyCollection<IMetadataText>
{
    /// <summary>
    ///     描述默认使用的上下文类型，此上下文一般和MDM文档中的 LabelType 对应。
    /// </summary>
    string Context { get; }

    /// <summary>
    ///     当前MDM文档描述是否是空。此属型只判断<see cref="IMetadataText" />成员对象的个数，
    ///     不检查成员文本是否是空。
    /// </summary>
    bool IsEmpty { get; }

    /// <summary>
    ///     获取当前MDM文档默认上下文类型和语言的描述文本。
    /// </summary>
    /// <returns>当前默认上下文和语言类型的文本，如果未设置，返回 null。</returns>
    string? GetText();

    /// <summary>
    ///     获取指定上下文和语言的描述文本。
    /// </summary>
    /// <param name="context">指定上下文类型</param>
    /// <param name="language">指定语言类型</param>
    /// <returns>对应上下文和语言类型的文本，如不存在，返回 null。</returns>
    string? GetText(string context, string language);

    /// <summary>
    ///     设置当前MDM文档上下文和语言类型下的文本。
    /// </summary>
    /// <param name="text">设置的新文本</param>
    void SetText(string text);

    /// <summary>
    ///     设置指定上下文类型和语言下的文本。
    /// </summary>
    /// <param name="context">指定上下文类型</param>
    /// <param name="language">指定语言</param>
    /// <param name="text">需要设置的描述文本</param>
    /// <param name="cdata">如果此文本在原始xml中处于CDATA中，将此参数设置为<see langword="true"/></param>
    void SetText(string context, string language, string text, bool cdata = false);
}


/// <summary>
///     多标签类型的标签对象集合。
/// </summary>
public interface IMetadataLabels : IMetadataStringKeyCollection<IMetadataLabel>
{
    /// <summary>
    ///     文本所在的文档对象。
    /// </summary>
    IMetadataDocument Document { get; }

    /// <summary>
    ///     设置指定标签类型、上下文类型、语言下的标签文本。
    /// </summary>
    /// <param name="labelType">标签类型</param>
    /// <param name="context">上下文类型</param>
    /// <param name="language">语言名</param>
    /// <param name="text">标签文本</param>
    /// <param name="cdata">是否指定XML中使用CDATA节点存储</param>
    void SetText(string labelType, string context, string language, string text, bool cdata = false);

    /// <summary>
    ///     获取默认上下文类型、标签类型、语言类型下的标签文本。
    /// </summary>
    /// <returns>如果没有配置默认标签类型、上下文类型、语言类型的文本，返回null，否则，返回当前值。</returns>
    string? GetText();

    /// <summary>
    ///     获取指定标签类型、上下文类型、语言类型下的标签文本。
    /// </summary>
    /// <param name="labelType">标签类型</param>
    /// <param name="context">上下文类型</param>
    /// <param name="language">语言名</param>
    /// <returns>如果没有配置指定标签类型、上下文类型、语言类型的文本，返回null，否则，返回当前值。</returns>
    string? GetText(string labelType, string context, string language);

    /// <summary>
    ///     获取指定标签类型下的标签配置。
    /// </summary>
    /// <param name="labelType">标签类型</param>
    /// <returns>如果给定标签类型在集合中，返回已有对象，否则，返回null</returns>
    IMetadataLabel? Get(string labelType);

    /// <summary>
    ///     获取或设置指定标签类型下的标签配置。
    /// </summary>
    /// <param name="labelType">标签类型</param>
    /// <returns>如果给定标签类型存在，返回已有对象，否则，新添加一个标签对象并返回。</returns>
    IMetadataLabel GetOrAdd(string labelType);
}